/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * Base class for creating Sortable lists
 * 
 * @author Telem
 * @param <DataType>
 *            The type of data you want to sort
 */
public class SortableList<DataType> implements SortableCollection<DataType>,
		List<DataType> {

	// FIXME : as the sorter are used right now, it is totally useless to
	// statically define a sorter for a list. either sorter evolves to integrate
	// add/remove/etc functions and react from this, and the sorter becomes the
	// one who possesses the sorted list (it's so stupid right now), or the
	// setsorter functions will be removed (though the first solution seems far
	// more adapted/intelligent).

	/** The real list of rounds, with no specific order */
	private List<DataType> data = new ArrayList<DataType>();

	/** The list of rounds, sorted according to the Sorter */
	private List<DataType> sortedDatas = null;

	/** The sorter currently used */
	private Sorter<DataType> sorter = null;

	public Sorter<DataType> getSorter() {
		return sorter;
	}

	public void setSorter(Sorter<DataType> sorter) {
		this.sorter = sorter;
		sortedDatas = null;
	}

	public void sort() {
		sort(this.sorter);
	}

	public void sort(Sorter<DataType> sorter) {
		if (sorter != null) {
			List<DataType> dataUsed = new ArrayList<DataType>(
					(sortedDatas != null) ? sortedDatas : data);
			sortedDatas = sorter.sort(dataUsed);
		} else
			sortedDatas = new ArrayList<DataType>(data);
	}

	public List<DataType> getSortedList() {
		if (sortedDatas == null)
			sort();
		return sortedDatas;
	}

	/**
	 * Sets the sortedData out of the real data. This differs from the sort
	 * method, which sets the sortedData out of the previous sortedData.
	 */
	public void resort() {
		sortedDatas = null;
		sort();
	}

	public boolean add(DataType arg0) {
		return data.add(arg0);
	}

	public void add(int arg0, DataType arg1) {
		data.add(arg0, arg1);
	}

	public boolean addAll(Collection<? extends DataType> arg0) {
		return data.addAll(arg0);
	}

	public boolean addAll(int arg0, Collection<? extends DataType> arg1) {
		return data.addAll(arg0, arg1);
	}

	public void clear() {
		data.clear();
	}

	public boolean contains(Object arg0) {
		return data.contains(arg0);
	}

	public boolean containsAll(Collection<?> arg0) {
		return data.containsAll(arg0);
	}

	public boolean equals(Object arg0) {
		return data.equals(arg0);
	}

	public DataType get(int arg0) {
		return data.get(arg0);
	}

	public int indexOf(Object arg0) {
		return data.indexOf(arg0);
	}

	public boolean isEmpty() {
		return data.isEmpty();
	}

	public Iterator<DataType> iterator() {
		return data.iterator();
	}

	public int lastIndexOf(Object arg0) {
		return data.lastIndexOf(arg0);
	}

	public ListIterator<DataType> listIterator() {
		return data.listIterator();
	}

	public ListIterator<DataType> listIterator(int arg0) {
		return data.listIterator(arg0);
	}

	public DataType remove(int arg0) {
		return data.remove(arg0);
	}

	public boolean remove(Object arg0) {
		return data.remove(arg0);
	}

	public boolean removeAll(Collection<?> arg0) {
		return data.removeAll(arg0);
	}

	public boolean retainAll(Collection<?> arg0) {
		return data.retainAll(arg0);
	}

	public DataType set(int arg0, DataType arg1) {
		return data.set(arg0, arg1);
	}

	public int size() {
		return data.size();
	}

	public List<DataType> subList(int arg0, int arg1) {
		return data.subList(arg0, arg1);
	}

	public Object[] toArray() {
		return data.toArray();
	}

	public <T> T[] toArray(T[] arg0) {
		return data.toArray(arg0);
	}

}
